게시글을 조회했을 때, 조회수가 증가하는데, 문제는 새로고침해도 조회수가 계속 증가한다는 피드백이 있었다.이를 보완하기 위해 찾아보다가 방법을 찾았고, 적용도 성공해서 적어본다.
변경 전| Post.java
...@Column(columnDefinition = "integer default 0", nullable = false)private int hits;...조회 수를 나타내는 필드이다.| PostService.java
@Transactionalpublic ResponseEntity readPost(Long postId, MemberDetails memberDetails) {...// 조회 수 증가updateHits(postId);...}// 조회수 증가 로직@Transactionalpublic int updateHits(Long id) {return postRepository.updateHits(id);}게시글 조회 시, 조회 수가 증가되도록 구현했다.하지만 이렇게 구현하면, 게시글에 접근할 때마다 조회 수가 증가한다.| PostRepository.java
public interface PostRepository extends JpaRepository {...@Modifying@Query("update Post p set p.hits = p.hits + 1 where p.id = :id")int updateHits(Long id);}특정 게시글 ID의 hits(조회 수)를 증가시킨다.@Modifying 어노테이션은 @Query 어노테이션에서 작성된 조회를 제외한 데이터의 변경이 있는삽입(Insert), 수정(Update), 삭제(Delete) 쿼리 사용시 필요한 어노테이션이다.변경 후서버게시글 상세 페이지에 접근하면, 조회 수가 증가되기 때문에, readPost()메소드에 조회 수 중복을 방지하는 로직을 추가했다.
| PostService.java
@Transactionalpublic ResponseEntity readPost(Long postId, MemberDetails memberDetails, HttpServletRequest request, HttpServletResponse response) {...// 조회 수 중복 방지Cookie oldCookie = null;Cookie[] cookies = request.getCookies();if (cookies != null) {for (Cookie cookie : cookies) {if (cookie.getName().equals("postView")) {oldCookie = cookie;}}}if (oldCookie != null) {if (!oldCookie.getValue().contains("["+ postId.toString() +"]")) {updateHits(postId);oldCookie.setValue(oldCookie.getValue() + "_[" + postId + "]");oldCookie.setPath("/");oldCookie.setMaxAge(60 * 60 * 24);response.addCookie(oldCookie);}} else {updateHits(postId);Cookie newCookie = new Cookie("postView", "[" + postId + "]");newCookie.setPath("/");newCookie.setMaxAge(60 * 60 * 24);response.addCookie(newCookie);System.out.println(newCookie);}...}// 조회수 증가 로직@Transactionalpublic int updateHits(Long id) {return postRepository.updateHits(id);}쿠키를 사용해서 게시글에 접근할 때마다 조회 수가 증가하는 것을 방지한다.쿠키를 통해 한 번 게시글을 조회했으면 재접근했을 때 조회 수가 증가되지 않도록 함클라이언트| post-details.js
// 게시글 상세 읽기function getPost() {...$.ajax({type: 'GET',url: process.env.BACKEND_HOST + '/post/' + params['id'],xhrFields: {withCredentials: true},...});}서버는 8080, 클라이언트는 5000번을 쓰기 때문에 서로 출처가 다르다. 이렇게 되면 쿠키를 통해 통신을 할 수 없는데(클라이언트에서 서버로 요청 시, 자동으로 쿠키가 요청 메시지에 담기지 않음), 이를 해결하기 위해 withCredentials = true로 해주어야 한다.
서버에서 쿠키를 보내기 때문에, 사용하기 위해선 클라이언트에서 쿠키로 통신하는 것을 허락해야 한다.따라서, xhrFields: { withCredentials: true },를 추가했다.클라이언트와 서버가 쿠키 값을 공유하겠다는 의미결과97, 99, 102번 게시글에 접근했고, 해당 게시글에 재접근해도 조회 수가 중복되어 증가되지 않는다!게시글에 접근하면, 조회 수가 증가하고, 접근한 게시글 번호가 쿠키에 담긴다.접근한 게시글에 재접근해도 이전과는 다르게 조회 수가 증가하지 않게 된다.
참고https://dev-coco.tistory.com/113#--%--%EC%A-%--%EC%-A%A-https://mighty96.github.io/til/view/https://kosaf04pyh.tistory.com/152